package com.example.tetris.logics.components;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;


// Board类用于管理游戏板上的方块状态
public class Board implements Serializable {
    private int width;
    private int height;
    private CellList cellsFixed;//存放的是已经固定了的，正在下落的块不在其中
    private boolean[][] board;//存放的是已经固定了的，正在下落的块不在其中




    public Board(int width, int height) {
        this.width = width;
        this.height = height;
        cellsFixed = new CellList();
        board = new boolean[height][width]; // false表示位置未被占据
    }

    public boolean isCellOccupied(int x, int y) {
        return board[y][x];
    }



    public boolean isOutOfBoundary(int x,int y){
        return  !(y >= 0 && y < height && x >= 0 && x < width);
    }

    public void occupyCell(int x, int y) {
        board[y][x] = true;
        cellsFixed.addCell(x,y);
    }

    private void clearCell(int x, int y) {
        board[y][x] = false;
        cellsFixed.deleteCell(x,y);
    }

    public boolean isRowFull(int y){
        boolean isFull = true;
        for (int x = 0; x < width; x++) {
            if(!isCellOccupied(x,y)){
                isFull = false;
                break;
            }
        }
        return isFull;
    }

    private void clearRow(int y){
        for (int x = 0; x < width; x++) {
            clearCell(x,y);
        }
        for (int row = y; row >= 0 ; row--) {
            for (int col = 0; col < width; col++) {
                if(row == 0){
                    board[row][col] = false;
                    continue;
                }
                board[row][col] = board[row - 1][col];
            }
        }
        for(Cell cell : cellsFixed.getCells()){
            if(cell.getY() < y){
                cell.setY(cell.getY() + 1);
            }
        }
    }

    public List<Integer> handleFullRows(){
        int fullRowCount = 0;
        List<Integer> fullRowsIndexList = new ArrayList<>();
        for (int y = 0; y < height; y++) {
            if(isRowFull(y)){
                fullRowsIndexList.add(y);
                fullRowCount++;
            }
        }

        for(int row : fullRowsIndexList){
            clearRow(row);
        }
        return fullRowsIndexList;
    }
    public CellList getCellsFixed() {
        return cellsFixed;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Board board1 = (Board) o;

        return width == board1.width && height == board1.height
                && Objects.equals(cellsFixed, board1.cellsFixed)
                && Arrays.deepEquals(board, board1.board);
    }

    @Override
    public int hashCode() {
        int result = Objects.hash(width, height, cellsFixed);
        result = 31 * result + Arrays.hashCode(board);
        return result;
    }
    @Override
    public String toString() {
        return "Board{" +
                "width=" + width +
                ", height=" + height +
                ", cellsFixed=" + cellsFixed +
                ", board=" + Arrays.toString(board) +
                '}';
    }

}